今日我們將快速瀏覽Spring Framework作為日後Spring MVC的基礎。
create day24 module
create resource folder
generate spring configuration file
Spring兩大核心概念DI與AOP。DI幫你解偶物件間的相依,不用再到處new物件了;AOP替你解偶程式流程耦合的橫切面關注。
談到Spring常會聽到Inversion of Control(IoC)控制反轉,反轉了物件生成控制權,將控制權交給了Spring Container,但IoC有多種的意思,筆者更頃向用Dependency Injection(DI)依賴注入說明它。
Aspect Oriented Programming (AOP)面向導向編程,關注cross-cutting concerns指的是非商業邏輯的關注點,像是logging、transactions、autit等。
DI Container是一個運行在JVM上的Java程式,它負責創建、配置、組裝物件與管理物件生命週期,所以他能容易整合AOP功能。它串建物建透過單純的POJO與設定檔資訊產生出符合系統使用的物件。
pom.xml引入spring使用的相關jar
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version> 6.1.13</version>
</dependency>
</dependencies>
前面提及的spring container創建物件是由pojo與configuration meta組合起來的,所以會有一個乘載設定檔的文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 最簡單的注入範例 -->
<bean id="emp01" class="com.swj.xml.Employee">
<property name="empNo" value="1234"></property>
<property name="name" value="joe"></property>
</bean>
<!-- 引入外部設定檔後可用${}來取用設定檔資訊 -->
<context:property-placeholder location="classpath:dbConfig.properties"></context:property-placeholder>
<!-- HikariCP connection pool setting -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<!-- jdbc setting -->
<property name="driverClassName" value="${db.driverClassName}" />
<property name="jdbcUrl" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
<!-- HikariCP parameter setting -->
<property name="maximumPoolSize" value="${db.hikari.maximumPoolSize}" />
<property name="minimumIdle" value="${db.hikari.minimumIdle}" />
<property name="idleTimeout" value="${db.hikari.idleTimeout}" />
<property name="connectionTimeout" value="${db.hikari.connectionTimeout}" />
<property name="maxLifetime" value="${db.hikari.maxLifetime}" />
</bean>
<bean id="empDao" class="com.swj.xml.EmpDao">
<constructor-arg ref="dataSource"></constructor-arg>
</bean>
<bean id="empService" class="com.swj.xml.EmpService">
<constructor-arg ref="empDao"></constructor-arg>
</bean>
<bean id="empController" class="com.swj.xml.EmpController">
<constructor-arg ref="empService"></constructor-arg>
</bean>
</beans>
# dbConfig.properties
db.driverClassName=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/mydb
db.username=root
db.password=1234
# connection pool setting
db.hikari.maximumPoolSize=10
db.hikari.minimumIdle=5
db.hikari.idleTimeout=30000
db.hikari.connectionTimeout=30000
db.hikari.maxLifetime=1800000
EmpController
public class EmpController {
private EmpService empService;
public void doEmpController() throws SQLException {
System.out.println("invoke doEmpController");
empService.doEmpService();
}
public EmpController(EmpService empService) {
this.empService = empService;
}
}
EmpService
public class EmpService {
private EmpDao empDao;
public void doEmpService() throws SQLException {
System.out.println("invoke doEmpService");
empDao.doEmpDao();
}
public EmpService(EmpDao empDao) {
this.empDao = empDao;
}
}
public class EmpDao {
private DataSource ds;
public void doEmpDao() throws SQLException {
System.out.println("invoke doEmpDao");
System.out.println("ds info:"+ds.getConnection());
}
public EmpDao(DataSource ds) {
this.ds = ds;
}
}
Employee
public class Employee {
String name;
String empNo;
//略getter、setter and toString
}
TestXml.java展示創建DI container並調用bean執行doEmpController方法
public class TestXml {
public static void main( String[] args ) throws SQLException {
ClassPathXmlApplicationContext container = new ClassPathXmlApplicationContext("beans.xml");
Employee emp01 = (Employee) container.getBean("emp01");
System.out.println(emp01);
EmpController controller = container.getBean(EmpController.class);
controller.doEmpController();
}
}